-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.


local lu = require 'luaunit'
local smbus = require 'protocol.smbus_5902'
local log = require 'mc.logging'
local utils = require 'mc.utils'

TestSmbus5902 = {}

local function to_raw(hex_data)
    local i = 0
    return hex_data:gsub('[^ ]+', function (data)
        return string.format('%c', tonumber(data, 16))
    end):gsub('.', function (data)
        i = i + 1
        return (i % 2 == 1) and data or ''
    end)
end

local function to_hex(data)
    return data:gsub('.', function(v)
        return string.format('%02X ', v:byte())
    end)
end

local old_getlevel = log.getLevel

local function make_log_level()
    log.getLevel = function()
        return 0xff
    end
end

local function recover_log_level()
    log.getLevel = old_getlevel
end

function TestSmbus5902:test_create_request()
    make_log_level()
    local args = {opcode = 0x5, length = 16}
    lu.assertEquals(to_hex(smbus:create_request(args)), '0C 80 00 05 00 00 00 00 00 10 00 00 00 ')
    args = {opcode = 0x3, length = 2}
    lu.assertEquals(to_hex(smbus:create_request(args)), '0C 80 00 03 00 00 00 00 00 02 00 00 00 ')
    args = {opcode = 0x2B, offset = 0x28000B00, length = 64}
    lu.assertEquals(to_hex(smbus:create_request(args)), '0C 80 00 2B 00 00 0B 00 28 40 00 00 00 ')
    recover_log_level()
end

function TestSmbus5902:test_parse_response()
    local rawdata = '1C 00 00 05 00 10 00 00 00 10 00 00 00 0A 01 0C 02 01 01 0C 02 02 02 02 00 02 02 02 00'
    local ret, data = smbus:parse_response(to_raw(rawdata))
    lu.assertEquals(ret, true)
    lu.assertEquals(to_hex(data), '0A 01 0C 02 01 01 0C 02 02 02 02 00 02 02 02 00 ')

    rawdata = '0E 00 00 03 00 02 00 00 00 02 00 00 00 2B 00'
    ret, data = smbus:parse_response(to_raw(rawdata))
    lu.assertEquals(ret, true)
    lu.assertEquals(to_hex(data), '2B 00 ')
end

function TestSmbus5902:test_read()
    local old_wait_for_idle = smbus.wait_for_idle
    local old_ref_chip = smbus.ref_chip
    local old_parse_response = smbus.parse_response
    local old_to_hex = utils.to_hex
    smbus.wait_for_idle = function()
        return true
    end
    smbus.ref_chip = {
        Read = function()
            return true, 0
        end
    }
    utils.to_hex = function()
        return ''
    end
    smbus.parse_response = function()
        return true
    end
    make_log_level()
    local ok, result= pcall(smbus.read, smbus, 6)
    lu.assertEquals(ok, true)
    lu.assertEquals(result, true)
    recover_log_level()
    smbus.ref_chip = old_ref_chip
    smbus.wait_for_idle = old_wait_for_idle
    smbus.parse_response = old_parse_response
    utils.to_hex = old_to_hex
end

function TestSmbus5902:test_write()
    local old_wait_for_idle = smbus.wait_for_idle
    local old_ref_chip = smbus.ref_chip
    local old_to_hex = utils.to_hex
    local old_create_request = smbus.create_request
    smbus.wait_for_idle = function()
        return true
    end
    smbus.ref_chip = {
        Write = function()
            return true, 0
        end
    }
    utils.to_hex = function()
        return ''
    end
    smbus.create_request = function()
        return true
    end
    make_log_level()
    local ok, result= pcall(smbus.write, smbus, 6)
    lu.assertEquals(ok, true)
    lu.assertEquals(result, true)
    recover_log_level()
    smbus.ref_chip = old_ref_chip
    smbus.wait_for_idle = old_wait_for_idle
    utils.to_hex = old_to_hex
    smbus.create_request = old_create_request
end